#include "videocallwidget.h"
#include "ui_videocallwidget.h"
#include "./tools/ui/paintshadow.h"
#include "./tools/ui/draghandler.h"
#include <QPainterPath>


bool VideoCallWidget::isTurnOn = false;

VideoCallWidget::VideoCallWidget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::VideoCall)
{
    ui->setupUi(this);

    // 移除标题栏和边框
    // this->setWindowFlags(Qt::FramelessWindowHint);
    // 设置窗口为透明，要不然阴影绘制没效果
    // this->setAttribute(Qt::WA_TranslucentBackground);
    // 安装事件过滤器让鼠标在任意位置拖动窗口
    DragHandler *dragHandler = new DragHandler(this);
    installEventFilter(dragHandler);

    initUI();
    initThread();

    /* UI和VideoHandler线程交互 */
    // UI线程控制摄像头的开闭
    connect(this, &VideoCallWidget::changeCameraStatus, m_videoHandler, &VideoHandler::onChangeCameraStatus);
    // VideoHandler线程回复UI线程摄像头初始化状态
    connect(m_videoHandler, &VideoHandler::initStatus, this, [this](bool status){
        if (!status)
        {
            QMessageBox::critical(this,"提示","没有发现摄像头");
        }
    });
    // UI线程通知VideoHandler线程切换摄像头
    connect(this, &VideoCallWidget::changeCamera, m_videoHandler, &VideoHandler::onChangeCamera);


    /* UI和ImageDealer线程交互 */
    //ImageDealer线程处理完毕，传给UI线程渲染
    connect(m_imageDealer, &ImageDealer::returnDealedImage, this, [=](const QImage flippedImage){
        this->m_curUserVideoWidget->videoSink()->setVideoFrame(QVideoFrame(flippedImage));
    });

    /* VideoHandler线程和ImageDealer线程交互 */
    // videoHandler线程捕获图像，传给ImageDealer线程
    connect(m_videoHandler, &VideoHandler::frameReadyToDeal, m_imageDealer, &ImageDealer::flipImage);

    /* UDPHandler线程和ImageDealer线程交互*/
    // ImageDealer线程处理好图片后发给UDPHandler线程
    connect(m_imageDealer, &ImageDealer::returnDealedImage, m_UDPHandler, &UDPHandler::sendImage);


    /* UI线程和和UDPHandler线程交互 */
    // 传递对方IP地址
    connect(this, &VideoCallWidget::getFriendIp, m_UDPHandler, &UDPHandler::onGetFriendIp);
    connect(m_UDPHandler, &UDPHandler::receiveImage, this, &VideoCallWidget::onReceivedImage);


    // 处理音频
    // QAudioInput* audioInput = new QAudioInput(this);
    // audioInput->setDevice(QMediaDevices::defaultAudioInput());  //获取默认的音频输入设备
    // session->setAudioInput(audioInput);     //设置音频输入设备

}



VideoCallWidget::~VideoCallWidget()
{
    delete ui;
    // qDebug() << "delete video widget";
    if (m_imageDealerThread && m_imageDealerThread->isRunning())
    {
        m_imageDealerThread->quit();
        m_imageDealerThread->wait();
        m_imageDealer->deleteLater();
        qDebug() << "delete image dealer thread";
    }

    if (m_videoHandler && m_videoHandlerThread->isRunning())
    {
        m_videoHandlerThread->quit();
        m_videoHandlerThread->wait();
        /*
        注意这里用deleteLater可能无法结束，因为此时摄像头是打开的状态，Qt会选择正确时间点析构，
        也就是摄像头停止捕获，所以析构函数不被调用，后续可以改成先发诵关闭摄像头信号，再deleteLater
        */
        delete m_videoHandler;
        qDebug() << "delete video dealer thread";
    }

    if (m_audioHandler && m_audioHandlerThread->isRunning())
    {
        m_audioHandlerThread->quit();
        m_audioHandlerThread->wait();
        m_audioHandler->deleteLater();
        qDebug() << "delete audio dealer thread";
    }

    if (m_UDPHandler && m_UDPHandlerThread->isRunning())
    {
        m_UDPHandlerThread->quit();
        m_UDPHandlerThread->wait();
        m_UDPHandler->deleteLater();
        qDebug() << "delete udp handler thread";
    }

}

void VideoCallWidget::setFriendIp(const QString& userId, const QString& friendId,
                                  const QString& friendIp)
{
    emit getFriendIp(userId, friendId, friendIp);
}


void VideoCallWidget::initUI()
{
    ui->ChooseCameraLabel->setStyleSheet("color: white;");
    // 初始化当前用户显示窗口
    m_curUserVideoWidget = new QVideoWidget(ui->curUserWidget);
    m_curUserVideoWidget->hide();
    // 设置m_curUserVideoWidget位置，并放在容器的合适位置（贴合容器）
    m_curUserVideoWidget->setGeometry(QRect(0, 0, ui->curUserWidget->width(), ui->curUserWidget->height()));
    // 初始化好友视频的显示窗口
    m_friendrVideoWidget = new QVideoWidget(ui->friendUserWidget);
    m_friendrVideoWidget->show();
    qDebug() << ui->friendUserWidget->width() << ui->friendUserWidget->height();
    m_friendrVideoWidget->setGeometry(QRect(0, 0, ui->friendUserWidget->width(), ui->friendUserWidget->height()));

    // 初始化摄像头选择下拉框
    initCameraCombobox();
    // 绑定摄像头开关按钮
    connect(ui->cameraStatusBtn, &QPushButton::clicked, this, &VideoCallWidget::onCameraStatusBtnClicked);

}

void VideoCallWidget::initThread()
{
    // 初始化图像处理线程
    m_imageDealerThread = new QThread(this);
    m_imageDealer = new ImageDealer;
    m_imageDealer->moveToThread(m_imageDealerThread);
    this->m_imageDealerThread->start();

    // 初始化视频采集线程
    m_videoHandlerThread = new QThread(this);
    m_videoHandler = new VideoHandler;
    m_videoHandler->moveToThread(m_videoHandlerThread);
    this->m_videoHandlerThread->start();

    // 初始化音频采集播放线程
    m_audioHandlerThread = new QThread(this);
    m_audioHandler = new AudioHandler;
    m_audioHandler->moveToThread(m_audioHandlerThread);
    this->m_audioHandlerThread->start();

    // 初始化UDP网络线程
    m_UDPHandlerThread = new QThread(this);
    m_UDPHandler = new UDPHandler;
    m_UDPHandler->moveToThread(m_UDPHandlerThread);
    this->m_UDPHandlerThread->start();
}

void VideoCallWidget::initCameraCombobox()
{
    int index = 0;  // 维护默认摄像头索引
    // 把所有检测到的摄像头显示到combobox
    for(int i = 0; i < QMediaDevices::videoInputs().size(); ++i)
    {
        QCameraDevice device = QMediaDevices::videoInputs().at(i);
        if (device.id() == QMediaDevices::defaultVideoInput().id()){
            ui->ChooseCameraBox->addItem(device.description() + "(默认)", QVariant::fromValue(device));
            index = i;
        }
        else
        {
            ui->ChooseCameraBox->addItem(device.description(), QVariant::fromValue(device));
        }
    }
    // combobox显示切换到默认摄像头
    ui->ChooseCameraBox->setCurrentIndex(index);

    // 切换combobox中的摄像头
    connect(ui->ChooseCameraBox, &QComboBox::currentIndexChanged, this, &VideoCallWidget::changeSelectedCamera);
    // 一进来显示默认摄像头
    changeSelectedCamera(ui->ChooseCameraBox->currentIndex());
}

void VideoCallWidget::changeSelectedCamera(int index)
{
    QVariant var=ui->ChooseCameraBox->itemData(index);
    QCameraDevice device = var.value<QCameraDevice>();
    qDebug() << "切换摄像头:" << device;
    emit changeCamera(device);
}

//发送截取的图片
void VideoCallWidget::SendImage(int id, const QImage &image)
{

    qDebug() << id;
    QString path = QDir::currentPath() + "/images/image.jpg";   //捕获图像的保存路径
    if (!image.isNull()) {  //截取到图片
        image.save(path, "jpg", 30);   //保存图像并压缩，质量为30
        QFile file(path);
        file.open(QIODevice::ReadOnly);
        // tcpSocket->write(file.readAll());   //发送图片
        // tcpSocket->flush();     //确保消息被发送
        file.close();
        qDebug() << "发送图片";
    }
    else
    {
        qDebug() << "没截到";
    }
}

// 将对方视频渲染到客户端
void VideoCallWidget::onReceivedImage(const QImage friendImage)
{
    qDebug() << "UI recieve data";
    this->m_friendrVideoWidget->videoSink()->setVideoFrame(QVideoFrame(friendImage));
    // 保存到本地
    bool success = friendImage.save("output.jpg");  // 也可以是 .jpg、.bmp 等
    qDebug() << "save status:" << success;
}


void VideoCallWidget::onCameraStatusBtnClicked()
{
    if (isTurnOn)
    {
        emit changeCameraStatus(false);
        this->m_curUserVideoWidget->hide();

        ui->cameraStatusBtn->setText(tr("打开摄像头"));
    }
    else
    {
        emit changeCameraStatus(true);
        this->m_curUserVideoWidget->show();

        ui->cameraStatusBtn->setText(tr("关闭摄像头"));
    }
    isTurnOn = !isTurnOn;
}


void VideoCallWidget::closeEvent(QCloseEvent *event)
{
    qDebug() << "Window closed and worker thread finished.";
    emit widgetClose();
    event->accept();
}


// void VideoCallWidget::paintEvent(QPaintEvent *event)
// {
//     QPainter painter(this);
//     painter.setPen(Qt::NoPen);  // 不显示边框
//     painter.setRenderHint(QPainter::SmoothPixmapTransform, true);   // 开启平滑渲染更丝滑
//     painter.setRenderHint(QPainter::Antialiasing, true);    // 开启抗锯齿更丝滑

//     if (!m_backgroundCache.isNull()) {
//         // 设置圆角矩形裁剪路径
//         QPainterPath path;
//         path.addRoundedRect(m_shadowWidth, m_shadowWidth, this->width() - 2 * m_shadowWidth, this->height() - 2 * m_shadowWidth, m_radius, m_radius);
//         painter.setClipPath(path);  // 设置剪切区域
//         // 将背景图片填充到窗口区域
//         painter.drawPixmap(m_shadowWidth, m_shadowWidth, this->width() - 2 * m_shadowWidth, this->height() - 2 * m_shadowWidth, m_backgroundCache);
//     }

//     QPainter painter2(this);
//     // 直接绘制缓存里的阴影边框
//     painter2.drawPixmap(0, 0, m_shadowCache);

//     QWidget::paintEvent(event);
// }

// void VideoCallWidget::resizeEvent(QResizeEvent *event)
// {
//     // 更新阴影边框的缓存
//     m_shadowCache = QPixmap(this->size());  // 创建一个与窗口大小一致的透明图层
//     m_shadowCache.fill(Qt::transparent);  // 填充透明色
//     PaintShadow sp(&m_shadowCache, m_shadowWidth, m_radius);


//     // 更新背景图片的缓存
//     m_backgroundCache = QPixmap(":/images/mainBackground.jpg");


//     QWidget::resizeEvent(event);
// }
